package com.jochen.core.world

import com.badlogic.gdx.Gdx
import com.artemis.*
import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.graphics.g2d.TextureRegion
import com.badlogic.gdx.math.*
import com.jochen.core.assets.AtlasAsset
import com.jochen.core.components.*
import kotlin.random.Random
import com.jochen.core.logic.*
import com.jochen.core.logic.resources.*
import com.jochen.core.logic.building.*
import com.jochen.core.system.*
import com.jochen.core.tools.*
object WorldGen {

    private const val MIN_DISTANCE_SQUARED = 2500f
    private val MPAOBJECTREGION = listOf<Int>(248,253,256,257,258)
    
    fun initWorld(game: GdxGame, world: World, bounds: Rectangle) {
        initMapObjects(game, world, bounds)
        val ent1 = createWay(world, 25f, 0f, true)                  // 右侧点
        val ent2 = createWay(world, 12.5f, 21.65f, true, ent1)      // 右上
        val ent3 = createWay(world, -12.5f, 21.65f, true, ent2)     // 左上
        val ent4 = createWay(world, -25f, 0f, true, ent3)           // 左侧点
        val ent5 = createWay(world, -12.5f, -21.65f, true, ent4)    // 左下
        val ent6 = createWay(world, 12.5f, -21.65f, true, ent5)     // 右下
        createRoad(world,ent6,ent1,true)
    }

    private fun initMapObjects(game: GdxGame, world: World, worldBounds: Rectangle) {
        val allPositions = mutableSetOf<Vector2>()

        repeat(200) {
            val entity = world.createEntity()
            val pos = randomPosition(allPositions, worldBounds)
            allPositions.add(pos)

            entity.edit().apply {
                create(Transform::class.java).apply {
                    position.set(pos)
                    z = 0
                    size.set(16f, 16f)
                    scaling.set(1f, 1f)
                    rotationDeg = 0f
                    sortOffsetY = 0f
                }
                val regionIndex = MathUtils.random(0,MPAOBJECTREGION.size - 1)
                val region = game.assetService.get(AtlasAsset.OBJECT).findRegion("${MPAOBJECTREGION.get(regionIndex)}")
                create(Sprite::class.java).apply {
                    this.region = region
                    color.set(1f, 1f, 1f, 0.8f)
                }
                create(MapObject::class.java).apply {
                    moveXY = MathUtils.randomBoolean()
                    this.oldPos.set(pos)
                    maxDistance = MathUtils.random(20f, 30f)
                    isAdd = true
                }
            }
        }
    }

    private fun randomPosition(existingPositions: Set<Vector2>, bounds: Rectangle): Vector2 {
        val maxAttempts = 100
        
        repeat(maxAttempts) {
            val candidate = randomRectPos(bounds)

            if (existingPositions.none { candidate.dst2(it) <= MIN_DISTANCE_SQUARED }) {
                return candidate
            }
        }
        
        // 如果找不到合适位置，返回随机位置
        return randomRectPos(bounds)
    }

    fun createWay(world: World, x: Float, y: Float,isFinis: Boolean,form: Int = -1) : Int{
        val entity = world.createEntity().apply{
            edit().apply {
                create(Sprite::class.java)
                create(Transform::class.java).apply {
                    position.set(x,y)
                    z = 3
                    size.set(20f, 20f)
                    scaling.set(1f, 1f)
                }
                create(ClickComponent::class.java)
                create(Building::class.java).apply{
                    unbuiltRes[BaseResources.MEAT] = 2
                    isConstructionFinished = isFinis
                    buildingData = BasePlatform.PLATFORM
                    MAX_LEVEL = buildingData.levelRegion.size
                }
            }
        }
        if(form != -1){
            createRoad(world,entity.id,form,isFinis)
        }
        return entity.id
    }
    
    fun createRoad(world: World, wayA: Int, wayB: Int,isFinis: Boolean = false): Int {
        val transformA = Mapper.transforms.get(wayA)
        val transformB = Mapper.transforms.get(wayB)
        
        if (transformA == null || transformB == null) return -1
        
        val mid = (transformA.position + transformB.position) * 0.5f 
        
        val atn = transformB.position - transformA.position
        val angle = Math.atan2(atn.y.toDouble(), atn.x.toDouble()).toFloat() * MathUtils.radiansToDegrees
        
        val distance = Vector2.dst(
        transformA.position.x, transformA.position.y,
        transformB.position.x, transformB.position.y)
        
        mid += transformA.size * transformA.scaling  * 0.5f
        
        val entity = world.createEntity().apply {
            edit().apply {
                create(Sprite::class.java)
                create(Transform::class.java).apply {
                    position.set(mid.x - (distance * 0.5f),mid.y - 2f)
                    z = 2
                    size.set(distance, 4f) 
                    rotationDeg = angle
                    scaling.set(1f,1f)
                }
                create(ClickComponent::class.java)
                create(Building::class.java).apply{
                    unbuiltRes[BaseResources.MEAT] = 2
                    isConstructionFinished = isFinis
                    buildingData = BasePlatform.ROAD
                    MAX_LEVEL = buildingData.levelRegion.size
                }
                create(RoadComponent::class.java).apply{
                    pointA = wayA
                    pointB = wayB
                }
            }
        }
        val roadId = entity.id
        Mapper.buildings.get(wayA).roadList.add(roadId)
        Mapper.buildings.get(wayB).roadList.add(roadId)
        return entity.id
    }
    
    
    private fun randomRectPos(rect: Rectangle): Vector2 {
    return Vector2(
        MathUtils.random(rect.x, rect.x + rect.width),
        MathUtils.random(rect.y, rect.y + rect.height)
        )
    }
    
}